package com.mongodb.samplemflix.service;

import com.mongodb.samplemflix.model.Movie;
import com.mongodb.samplemflix.model.dto.BatchInsertResponse;
import com.mongodb.samplemflix.model.dto.BatchUpdateResponse;
import com.mongodb.samplemflix.model.dto.CreateMovieRequest;
import com.mongodb.samplemflix.model.dto.DeleteResponse;
import com.mongodb.samplemflix.model.dto.DirectorStatisticsResult;
import com.mongodb.samplemflix.model.dto.MovieSearchQuery;
import com.mongodb.samplemflix.model.dto.MovieWithCommentsResult;
import com.mongodb.samplemflix.model.dto.MoviesByYearResult;
import com.mongodb.samplemflix.model.dto.UpdateMovieRequest;
import com.mongodb.samplemflix.model.dto.VectorSearchResult;
import java.util.List;
import org.bson.Document;

/**
 * Service interface for movie business logic.
 */
public interface MovieService {

    List<Movie> getAllMovies(MovieSearchQuery query);

    Movie getMovieById(String id);

    Movie createMovie(CreateMovieRequest request);

    BatchInsertResponse createMoviesBatch(List<CreateMovieRequest> requests);

    Movie updateMovie(String id, UpdateMovieRequest request);

    BatchUpdateResponse updateMoviesBatch(Document filter, Document update);

    DeleteResponse deleteMovie(String id);

    DeleteResponse deleteMoviesBatch(Document filter);

    Movie findAndDeleteMovie(String id);

    // Aggregation endpoints for reporting

    /**
     * Aggregates movies with their most recent comments.
     *
     * @param limit Maximum number of movies to return
     * @param movieId Optional movie ID to filter by specific movie
     * @return List of movies with their recent comments
     */
    List<MovieWithCommentsResult> getMoviesWithMostRecentComments(Integer limit, String movieId);

    /**
     * Aggregates movies by year with statistics.
     *
     * @return List of yearly statistics including movie count and average rating
     */
    List<MoviesByYearResult> getMoviesByYearWithStats();

    /**
     * Aggregates directors with the most movies.
     *
     * @param limit Maximum number of directors to return
     * @return List of directors with their movie count and average rating
     */
    List<DirectorStatisticsResult> getDirectorsWithMostMovies(Integer limit);

    // MongoDB Search endpoints

    /**
     * Searches movies using MongoDB Search across multiple fields.
     * Demonstrates text search using a Search Index with compound operators.
     *
     * <p>Supports searching across:
     * <ul>
     * <li>plot - using phrase operator for exact phrase matching</li>
     * <li>fullplot - using phrase operator for exact phrase matching</li>
     * <li>directors - using text operator with fuzzy matching</li>
     * <li>writers - using text operator with fuzzy matching</li>
     * <li>cast - using text operator with fuzzy matching</li>
     * </ul>
     *
     * @param searchRequest Search parameters including fields to search and compound operator
     * @return List of movies matching the search criteria
     */
    List<Movie> searchMovies(com.mongodb.samplemflix.model.dto.MovieSearchRequest searchRequest);

    /**
     * Finds similar movies using vector search on plot embeddings.
     * Demonstrates MongoDB Vector Search.
     *
     * @param movieId ID of the movie to find similar movies for
     * @param limit Maximum number of similar movies to return (default: 10, max: 50)
     * @return List of similar movies based on plot embeddings
     */
    List<Movie> findSimilarMovies(String movieId, Integer limit);

    /**
     * Searches movies using MongoDB Vector Search to find movies with similar plots.
     * Uses embeddings generated by the Voyage AI model to perform semantic similarity search.
     *
     * <p>This method:
     * <ul>
     * <li>Generates an embedding for the search query using Voyage AI</li>
     * <li>Performs vector search on the embedded_movies collection</li>
     * <li>Returns movies with similarity scores</li>
     * </ul>
     *
     * @param query Search query text to find movies with similar plots
     * @param limit Maximum number of results to return (default: 10, max: 50)
     * @return List of vector search results with movie information and similarity scores
     */
    List<VectorSearchResult> vectorSearchMovies(String query, Integer limit);
}
